package com.activiti;

import cn.hutool.core.collection.CollUtil;
import com.redpig.App;
import com.redpig.util.ActivitiUtils;
import lombok.SneakyThrows;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.io.FileUtils;
import org.dom4j.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.Instant;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

@SpringBootTest(classes = App.class)
public class ActivitiViewPic {

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    HistoryService historyService;

    /**
     * 查看部署的流程图:这里需要注意的是 部署zip中带png图片的才行
     */
    @SneakyThrows
    @Test
    public void testDelopymentImage(){
        List<ProcessDefinition> definitions = repositoryService.createProcessDefinitionQuery().list();

        for (ProcessDefinition definition : definitions) {

            String resourceName = repositoryService.getDeploymentResourceNames(definition.getDeploymentId()).stream().filter(e -> e.indexOf(".png") > 0).collect(Collectors.toList()).get(0);

            InputStream in = repositoryService.getResourceAsStream(definition.getDeploymentId(), resourceName);

            File file = new File("D:/pic/" + resourceName);
            FileUtils.copyInputStreamToFile(in, file);
        }
    }

    @SneakyThrows
    @Test
    public void testGenerateImage1(){
        BpmnModel bpmnModel = repositoryService.getBpmnModel("oa-leave:1:33da41eb-25f9-11ee-8792-1c1b0d7e2515");

        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

        //InputStream inputStream = generator.generateDiagram(bpmnModel, lastTask, Collections.emptyList(), "宋体", "宋体", "宋体", true, "test");
        InputStream inputStream = generator.generateDiagram(bpmnModel, "endEvent", "宋体", "宋体");

        String imageName = "image-" + Instant.now().getEpochSecond() + ".svg";
        FileUtils.copyInputStreamToFile(inputStream, new File("processes/" + imageName));

    }

    @SneakyThrows
    @Test
    public void test() {
        BpmnModel bpmnModel = repositoryService.getBpmnModel("oa-leave:1:ce37d4c3-2490-11ee-ba31-3413e841d179");

        String xmlContent = new String(new BpmnXMLConverter().convertToXML(bpmnModel), "UTF-8");
        Document document = DocumentHelper.parseText(xmlContent);

        Element root = document.getRootElement();

        List<Element> flowElements = root.elements();
        for (Element element : flowElements) {
            for (Object o : element.elements()) {
                Element ele = (Element) o;
                Attribute attribute = ele.attribute("bpmnElement");
                System.out.println("attribute = " + attribute);
            }
        }

    }

    @Autowired
    ActivitiUtils activitiUtils;

    @SneakyThrows
    @Test
    public void test02(){
        String processDefinitionId = "oa-leave:1:33da41eb-25f9-11ee-8792-1c1b0d7e2515";
        int[] endPlace = activitiUtils.getEndPlace(processDefinitionId);
        Arrays.stream(endPlace).forEach(System.out::println);
        int x = endPlace[0] * 2 - 23;
        int y = -endPlace[1] * 2 + 14;
        int width = endPlace[2] + 5;
        int height= endPlace[3] + 5;

        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();

        String resourceName = repositoryService.getDeploymentResourceNames(processDefinition.getDeploymentId()).stream().filter(e -> e.indexOf(".png") > 0).collect(Collectors.toList()).get(0);

        InputStream in = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);

        Image srcImg = ImageIO.read(in);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);

        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);


        g.setPaint(new Color(0, 255, 127));
        BasicStroke stokeLine = new BasicStroke(7.0f);
        g.setStroke(stokeLine);

        g.drawRoundRect(x, y, width,height,width,height);
        g.dispose();

        //待存储的地址
        String tarImgPath="d:/pic/oa-leave.png";
        // 输出图片
        FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
        ImageIO.write(bufImg, "png", outImgStream);
        System.out.println("添加水印完成");
        outImgStream.flush();
        outImgStream.close();

    }

    /**
     * 生成流程图
     *
     * @throws IOException 生成流程图异常！
     */
    @Test
    public void generateImage() throws IOException {

        List<Task> tasks = taskService.createTaskQuery()
                //.taskCandidateUser("zzx")
                .active()
                .list();
        Task task = tasks.get(0);
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId())
                .singleResult();

        BpmnModel model = repositoryService.getBpmnModel(task.getProcessDefinitionId());

        ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

        //全部经过的结点
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstance.getId())
                .orderByHistoricActivityInstanceId()
//                .asc()
                .desc()
                .list();
        List<String> highLightedActivityIds = historicActivityInstances.stream()
                .map(HistoricActivityInstance::getActivityId)
                .collect(Collectors.toList());

        //lastTask是当前任务执行到的位置
        List<HistoricActivityInstance> lastTasks =
                historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(processInstance.getId())
                        .orderByHistoricActivityInstanceStartTime()
                        .desc()
                        .list();
        List<String> lastTask = lastTasks.stream()
                .map(HistoricActivityInstance::getActivityId)
                .limit(1)
                .collect(Collectors.toList());
        lastTask.add(lastTasks.get(0).getActivityId());

        //七个参数分别是：
        //  BPMNModel
        //  高光节点
        //  高光顺序流
        //  活动字体名称
        //  标签字体名称
        //  批注字体名称
        //  生成默认关系图
        //  默认关系图映像文件名
        InputStream inputStream = generator.generateDiagram(
                model, lastTask, Collections.emptyList(), "宋体", "宋体", "宋体", true, "test");

        String imageName = "image-" + Instant.now().getEpochSecond() + ".svg";
        FileUtils.copyInputStreamToFile(inputStream, new File("processes/" + imageName));


    }

}
